<?php

namespace App;

use swoole\server as sw;
use App\Pickup as pu;

class Index
{
    private $serv;
    private $task_num;

    public function __construct()
    {
        $cnf        = getConfig();
        $this->serv = new sw($cnf->swoole->host, $cnf->swoole->port);
        $this->serv->set([
            'worker_num'    => $cnf->swoole->worker_num,
            'daemonize'     => $cnf->swoole->daemonize,
            'max_request'   => $cnf->swoole->max_request,
            'dispatch_mode' => $cnf->swoole->dispatch_mode,
            'log_file'      => $cnf->swoole->log_file
        ]);
        $this->task_num = $cnf->swoole->task_num;
        $this->serv->on('Receive', [$this, 'onReceive']);
        $this->serv->on('WorkerStart', [$this, 'onWorkerStart']);
        $this->serv->on('WorkerStop', [$this, 'onWorkerStop']);
        $this->serv->on('ManagerStart', [$this, 'onManagerStart']);
        $this->serv->start();
    }

    public function onManagerStart(sw $serv)
    {
        global $argv;
        swoole_set_process_name("php {$argv[0]}: Manager");
    }

    public function onReceive(sw $serv, $fd, $from_id, $data)
    {
        \Log::out('launch', 'receive:' . $data);
        if ($data == 'shutdown') {
            $serv->send($fd, 'SHUTDOWN');
            $serv->close($fd);
            $serv->shutdown();
        } else {
            $serv->send($fd, 'START');
            $this->task();
        }
    }

    public function onWorkerStart(sw $serv, $worker_id)
    {
        \Log::out('launch', "[worker start]:{$worker_id} at " . date('Y-m-d H:i:s'));
        global $argv;
        if ($serv->taskworker) {
            swoole_set_process_name("php {$argv[0]}: Task");
        } else {
            swoole_set_process_name("php {$argv[0]}: Worker");
        }
        $this->task();
    }

    private function task()
    {
        \Log::out('launch', "[running]: at " . date('Y-m-d H:i:s'));        
        for ($tasker = 0; $tasker < $this->task_num; $tasker++) {
            go(function () use ($tasker, $qlist) {                
                $cache = \RedisPool::get();
                $db    = \MysqlPool::get();
                $puer  = new pu($cache, $db);
                while ($cache->llen('queue') > 0 && $url = $cache->rPop('queue')) {
                    \Log::out('launch', '[picking-' . $tasker . ']:' . $url);
                    $puer->pick($tasker, $url);
                }				
                \RedisPool::put($cache);
                \MysqlPool::put($db);
                \Log::out('launch', "[over-{$tasker}]: at " . date('Y-m-d H:i:s'));
            });
        }
    }

    public function onWorkerStop(sw $serv, $worker_id)
    {
        \Log::out('launch', "[worker stop]: {$worker_id} at " . date('Y-m-d H:i:s'));
        $serv->shutdown();
    }

}
